# 添加 aidl 文件
添加 aidl 文件 frameworks/base/core/java/android/os/IHelloService.aidl
:
package android.os;
interface IHelloService
{
void open();
void write(String str);
String read();
}
2
3
4
5
6
7
8
在 frameworks/base/Android.mk
中添加上 aidl 文件:
LOCAL_SRC_FILES += \
core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
core/java/android/accounts/IAccountManager.aidl \
core/java/android/accounts/IAccountManagerResponse.aidl \
core/java/android/accounts/IAccountAuthenticator.aidl \
# .......
core/java/android/os/IHelloService.aidl \ # 添加的内容
core/java/android/security/IKeystoreService.aidl \
core/java/android/service/carrier/ICarrierService.aidl
# ......
2
3
4
5
6
7
8
9
10
11
# 实现服务端
添加 frameworks/base/services/core/java/com/android/server/HelloService.java
文件:
package com.android.server;
import android.os.IHelloService;
// 硬件服务的服务端实现
public class HelloService extends IHelloService.Stub {
public native void natvieOpen();
public native void natvieWrite(String str);
public native String nativeRead();
public void open() throws android.os.RemoteException {
natvieOpen();
}
public void write(String str) throws android.os.RemoteException {
natvieWrite(str);
}
public String read() throws android.os.RemoteException {
return nativeRead();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# JNI 层实现
添加 frameworks/base/services/core/jni/com_android_server_HelloService.cpp
JNI 实现:
#define LOG_TAG "HelloService"
#include <jni.h>
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hello_hal.h>
#include <stdio.h>
#include <string>
namespace android
{
static hw_module_t *gHelloModule = NULL;
static hello_hal_device_t *gHelloHalDevice = NULL;
static void helloOpen(JNIEnv env, jobject clazz)
{
ALOGD("yuandaima_jni_open");
if (gHelloModule != NULL) {
return;
}
int err = hw_get_module(HELLO_HAL_HARDWARE_MODULE_ID, (hw_module_t const**)&gHelloModule);
if (err) {
ALOGE("Couldn't load %s module (%s)", HELLO_HAL_HARDWARE_MODULE_ID, strerror(-err));
} else {
if (gHelloModule) {
ALOGD("yuandaima_jni_open get module sucess");
hello_hal_methods_open(gHelloModule, &gHelloHalDevice);
}
}
if(gHelloHalDevice) {
gHelloHalDevice->hello_hal_open(gHelloHalDevice);
}
}
static void helloWrite(JNIEnv* env, jobject clazz, jstring str)
{
if (gHelloHalDevice) {
ALOGD("yuandaima_jni_write");
const char * c_str = NULL;
jboolean isCopy;
c_str = env->GetStringUTFChars(str, &isCopy); //从jstring指针中获取数据
ALOGD("yuandaima_jni_write %s",c_str);
gHelloHalDevice->hello_hal_write(gHelloHalDevice, c_str);
}
else {
ALOGW("Tried to hello but there is no hello device.");
}
}
static jstring helloRead(JNIEnv* env, jobject clazz)
{
if (gHelloHalDevice) {
ALOGD("yuandaima_jni_read");
char* data = NULL;
gHelloHalDevice->hello_hal_read(gHelloHalDevice, &data);
ALOGD("yuandaima_jni_read result is %s", data);
if(data != NULL ) {
// Android7 上直接用 NewStringUTF 把 char* 转 jstring 有乱码缺码 bug
jbyteArray array = env->NewByteArray(1024);
env->SetByteArrayRegion(array, 0, 1024,(const jbyte *)data);
jstring strEncode = env->NewStringUTF("UTF-8");
jclass cls = env->FindClass("java/lang/String");
jmethodID ctor = env->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
jstring ret = (jstring) env->NewObject(cls, ctor, array, strEncode);
return ret;
}
}
return env->NewStringUTF("no msg");
}
// public native void natvieOpen();
// public native void natvieWrite(String str);
// public native String nativeRead();
static const JNINativeMethod method_table[] = {
{ "natvieOpen", "()V", (void*)helloOpen },
{ "natvieWrite", "(Ljava/lang/String;)V", (void*)helloWrite },
{ "nativeRead", "()Ljava/lang/String;", (void*)helloRead }
};
int register_android_server_HelloService(JNIEnv *env)
{
ALOGD("yuandaima_jni_register");
return jniRegisterNativeMethods(env, "com/android/server/HelloService",
method_table, NELEM(method_table));
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
在 frameworks/base/services/core/jni/Android.mk
中添加:
LOCAL_SRC_FILES += \
# ......
$(LOCAL_REL_DIR)/com_android_server_UsbMidiDevice.cpp \
$(LOCAL_REL_DIR)/com_android_server_UsbHostManager.cpp \
$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
$(LOCAL_REL_DIR)/com_android_server_HelloService.cpp \ # 添加的内容
$(LOCAL_REL_DIR)/com_android_server_PersistentDataBlockService.cpp \
$(LOCAL_REL_DIR)/onload.cpp
2
3
4
5
6
7
8
在 frameworks/base/services/core/jni/onload.cpp
中添加:
namespace android {
// ......
int register_android_server_vr_VrManagerService(JNIEnv* env);
//添加的内容
int register_android_server_HelloService(JNIEnv* env);
int register_android_server_VibratorService(JNIEnv* env);
int register_android_server_location_GnssLocationProvider(JNIEnv* env);
int register_android_server_connectivity_Vpn(JNIEnv* env);
// .....
}
// 在这里注册 JNI 函数
// java 层的 native 方法就能调用到对应的 native 层函数了
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
ALOGE("GetEnv failed!");
return result;
}
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_ActivityManagerService(env);
register_android_server_PowerManagerService(env);
// ......
register_android_server_VibratorService(env);
// 添加的内容
register_android_server_HelloService(env);
register_android_server_SystemServer(env);
register_android_server_location_GnssLocationProvider(env);
register_android_server_location_FlpHardwareProvider(env);
// ......
return JNI_VERSION_1_4;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
修改 frameworks/base/services/java/com/android/server/SystemServer.java
:
private void startBootstrapServices() {
traceBeginAndSlog("StartHelloService");
hello = new HelloService();
ServiceManager.addService("HelloService", hello);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
2
3
4
5
6
# 客户端实现
添加一个接口 frameworks/base/core/java/android/os/HelloHal.java
:
package android.os;
import android.app.ActivityThread;
import android.content.Context;
public abstract class HelloHal {
public HelloHal() {
}
public abstract int open() throws RemoteException;
public abstract int write(String st) throws RemoteException;
public abstract String read() throws RemoteException;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
实现接口 frameworks/base/core/java/android/os/SystemHelloHal.java
:
package android.os;
import android.content.Context;
import android.util.Log;
/**
* Vibrator implementation that controls the main system vibrator.
*
* @hide
*/
public class SystemHelloHal extends HelloHal {
private static final String TAG = "HelloHal";
private final IHelloService mService;
// 获取Hello服务的代理端
public SystemHelloHal() {
mService = IHelloService.Stub.asInterface(
ServiceManager.getService("hello"));
}
// 通过代理端对象发起远程调用
@Override
public int open() throws RemoteException{
if (mService != null) {
mService.open();
}
return -1;
}
@Override
public int write(String str) throws RemoteException {
if (mService != null) {
mService.write(str);
}
return -1;
}
@Override
public String read() throws RemoteException {
if (mService != null) {
return mService.read();
}
return null;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
在 frameworks/base/core/java/android/content/Context.java
中添加:
public static final String HELLO_SERVICE = "hello";
@StringDef(suffix = { "_SERVICE" }, value = {
HELLO_SERVICE,
POWER_SERVICE,
//......
2
3
4
5
6
最后在 SystemServiceRegistry 的静态块中添加:
// frameworks/base/core/java/android/app/SystemServiceRegistry.java
static {
registerService(Context.HELLO_SERVICE, HelloHal.class,
new CachedServiceFetcher<HelloHal>() {
@Override
public HelloHal createService(ContextImpl ctx) {
return new SystemHelloHal();
}});
}
2
3
4
5
6
7
8
9
# Selinux 配置
修改 system/sepolicy/service.te:
type HelloServiceType, app_api_service, system_server_service, service_manager_type;
修改 system/sepolicy/service_contexts:
HelloService u:object_r:HelloServiceType:s0
修改 system/sepolicy/platform_app.te,让系统 App 可以访问我们自定义的 Binder 服务:
allow platform_app HelloServiceType:service_manager find;
修改 system/sepolicy/untrusted_app.te,让普通 App 可以访问我们自定义的 Binder 服务:
allow untrusted_app HelloServiceType:service_manager find;
最后,让 SystemServer 可以访问到 hello 驱动,修改 system/sepolicy/system_server.te
:
allow system_server hello_dev_t:chr_file { open read write };
# 编译
source build/envsetup.sh
lunch aosp_x86_64-eng
# 在 com.android.server 包中添加了 HelloService 后,给系统添加了 API
make update-api
make -j32
# 启动模拟器
emulator -kernel /tmp/kernel-qemu/x86_64-3.10.0/kernel-qemu
2
3
4
5
6
7
# 参考资料
Android Native 开发之 NewString 与 NewStringUtf 解析 (opens new window)